home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / TEXUTILS / rtf2LaTeX / c / rtf2LaTeX < prev   
Text File  |  1996-09-03  |  68KB  |  2,809 lines

  1. /*
  2.  * An output filter to produce LaTeX using Paul DuBois' RTF reader
  3.  * WECHTL Erwin
  4.  * Woerthg. 2/18
  5.  * A-2500 Baden
  6.  * AUSTRIA
  7.  *
  8.  * a student of the University in vienna
  9.  * Technische Universitaet Wien
  10.  * Institut fuer Technische Informatik
  11.  * Treitlstr. 3
  12.  * A-1040 WIEN
  13.  * AUSTRIA
  14.  *
  15.  * Changed code from:
  16.  *
  17.  * Written and copyright (c) 1991 by Robert Lupton (rhl@astro.princeton.edu)
  18.  * Permission is granted to freely distribute and modify this code, providing:
  19.  *    1/ This copyright notice is preserved
  20.  *    2/ You send me a copy of any changes for inclusion in a future release
  21.  */
  22. #include <stdio.h>
  23. #ifdef __riscos
  24. #  include <4SharedC/ctype.h>
  25. void   *xosfile_set_type(char *, int);
  26. #define FileType_TeX   0x2a7
  27. #define FileType_LaTeX 0x2a8
  28. #else
  29. #  include <ctype.h>
  30. #endif
  31. #include <string.h>
  32. #ifdef __STDC__
  33. #   include <stdlib.h>
  34. #   ifndef THINK_C
  35. #      include <unistd.h>
  36. #   endif
  37. #else /* !__STDC__ */
  38. #   ifdef NO_MALLOC_H
  39.         extern char     *malloc ();
  40. #   else /* NO_MALLOC_H */
  41. #       include    <malloc.h>
  42. #   endif /* NO_MALLOC_H */
  43. #endif /* !__STDC__ */
  44. #ifndef SEEK_SET
  45. #   define SEEK_SET 0
  46. #endif
  47. #include "fonts.h"
  48. #include "r2L_version.h"
  49. #include "rtf2LaTeX.h"
  50. #include "rtf.h"
  51.  
  52. #ifdef THINK_C
  53. #include <console.h>
  54. #include "macintosh.h"
  55. static char * RTFDIR;
  56. #endif
  57.  
  58. #ifdef __riscos
  59. char *RTFDIR = "RTFDIR:";
  60. #endif
  61.  
  62.  
  63.  
  64. FILE *outfp = stdout; /* Changed - I don't like using stdout only */
  65. char *progname;    /* Used in Error messages */
  66. RTFFuncPtr default_read_font = NULL;    /* default func to read style table */
  67. RTFFuncPtr default_read_style = NULL;    /* default func to read style table */
  68.  
  69. /* This forward declaration isn't possible in the header file because
  70.  * RTFStyle isn't defined there yet.
  71.  */
  72. static int is_specialWORDstyle A((RTFStyle*,LATEXStyle*));
  73. /*****************************************************************************/
  74. int
  75. main(ac,av)
  76. int ac;
  77. char *av[];
  78. {
  79.    RTF_STACK rtf_initial;        /* initial values of things that
  80.                        on rtf stack */
  81.  
  82.    static char *header_erwinbet[] = {
  83.       "% Converted from RTF format using rtf2LaTeX",
  84.       "% Comments and bugs to Erwin Wechtl",
  85.       "%                      Woertg. 2/18",
  86.       "%                      A-2500 Baden",
  87.       "%",
  88.       NULL,
  89.    };
  90.  
  91.  
  92. FILE *fil = NULL;
  93. extern int optind;
  94. extern char *optarg;
  95. int c;
  96. char *codefile = "ansi", *landfile = "english";
  97. char *str = "12345.67";
  98. char *rtf_filename = NULL;
  99.  
  100. #ifdef THINK_C
  101.    RTFDIR = get_home_dir();
  102.    ac = ccommand(&av);
  103. #endif /* THINK_C */
  104.  
  105.    progname = av[0];
  106. #ifdef __riscos
  107.    while((c = getopt(ac,av,"cC:dhgGHL:no:pqrR:stT:uv:V")) != EOF)
  108. #else
  109.    while((c = getopt(ac,av,"cC:dhgGHL:no:pqrstT:uv:V")) != EOF)
  110. #endif
  111.       {
  112.       switch (c)
  113.        {
  114.        case 'g':
  115.      german_squotes = 1;
  116.      break;
  117.        case 'G':
  118.      german_dquotes = 1;
  119.      break;
  120.        case 'q':
  121.      translate_quotes = 1;
  122.      break;
  123.        case 'C':
  124.      codefile = optarg;
  125.      break;
  126.        case 'c':            /* don't do character formating */
  127.      formatting_char= 0;
  128.      break;
  129.        case 'd':            /* formate also in specila WORD styles like heading, footer, footnote text, .. (default 0) */
  130.      formatting_sWORD = 1;
  131.      break;
  132.        case 'h':
  133.      usage();
  134.      exit(0);
  135.        case 'H':            /* use LaTeX default header and footer */
  136.      header_on = 0;
  137.      break;
  138.        case 'L':
  139.      landfile = optarg;
  140.      break;
  141.        case 'n':
  142.      other_linebreak = 1;           /* use \hfil\break instead of \\ */
  143.      break;                         /* for making a new line         */
  144.        case 'o':
  145.          if ((outfp = fopen(optarg,"w")) == NULL) /* modified for more convenience */
  146.          {
  147.            fprintf(stderr,"Error opening output file %s\n",optarg);
  148.            exit(0);
  149.          }
  150.          osfile_set_type(optarg,FileType_LaTeX);
  151.          break;
  152.        case 'p':            /* don't do paragraph formating */
  153.      formatting_para =  0;
  154.      break;
  155.        case 'r':            /* ignore left and right skip */
  156.      rl_skip_on = 0;
  157.      break;
  158. #ifdef __riscos
  159.        case 'R':
  160.          RTFDIR = optarg;
  161.          break;
  162. #endif
  163.        case 's':            /* ignore tab stops */
  164.      tabstops_on = 0;
  165.      break;
  166.        case 't':            /* don't do any formating in tables */
  167.      formatting_table =  0;
  168.      break;
  169.        case 'T':            /* decrease cell-width (default 0.7)*/
  170.      smaller_cell_factor=atof(optarg);
  171.      if (!(smaller_cell_factor > 0))
  172.         {
  173.         fprintf(stderr,"\n%s: Argument of the -T flag must be greater than 0,\n but it is %g\n", progname, smaller_cell_factor);
  174.         fprintf(stderr,"use -h for help\n");
  175.         exit(2);
  176.         }
  177.      break;
  178.        case 'u':            /* change underline to italic */
  179.      noUnderline = 1;
  180.      break;
  181.        case 'v':
  182.      verbose = atoi(optarg);
  183.      if (verbose!=1 && verbose!=2)
  184.         {
  185.         fprintf(stderr,"\n%s: The level of verbose can only be 1 or 2\n", progname);
  186.         fprintf(stderr,"use -h for help\n");
  187.         exit(2);
  188.         }
  189.      break;
  190.        case 'V':
  191.      fprintf(stderr,"%s: %s\n",progname,version);
  192.      exit(0);
  193.      break;
  194.        case '?':
  195.      fprintf(stderr,"%s: ", progname);
  196.      usage();
  197.      exit(2);
  198.       }
  199.     }
  200.   if (optind<ac)
  201.   {
  202.       if ((strchr(av[optind],'.')) != NULL)
  203.     rtf_filename = av[optind];
  204.       else
  205.       {
  206.     if((rtf_filename = malloc(strlen(av[optind]) + 5)) == NULL)
  207.     {
  208.         fprintf(stderr,"%s: Error in malloc\n", progname);
  209.         exit(3);
  210.     }
  211.     strcpy(rtf_filename, av[optind]);
  212.           #ifdef __riscos
  213.           strcat(rtf_filename,"/rtf");
  214.           #else
  215.           strcat(rtf_filename,".rtf");
  216.           #endif
  217.       }
  218.   }
  219. #ifdef THINK_C
  220.   else rtf_filename = get_file_from_dialog();
  221.   if (!rtf_filename) exit(0);
  222. #endif
  223.   if(rtf_filename != NULL)
  224.   {
  225.       if((fil = fopen(rtf_filename,"r")) == NULL)
  226.       {
  227.      fprintf(stderr,"%s: Can't open %s\n",progname,rtf_filename);
  228.      exit(1);
  229.       }
  230.       RTFSetStream(fil);
  231.   }
  232.   if (optind+1<ac)
  233.     {
  234.     fprintf(stderr,"%s: After the filename (%s) there are no more arguments or flags allowed!\n", progname, av[optind]);
  235.     fprintf(stderr,"use -h for help\n");
  236.     exit(2);
  237.     }
  238.  
  239.    rtf_default.LaTeX_stack = NULL;    /* the rtf stack */
  240.    rtf_default.char_attr = char_attr;
  241.    rtf_default.par_attr = par_attr;
  242.    rtf_default.style = -1;
  243.    rtf_default.prev = NULL;
  244.    rtf_current = rtf_initial = rtf_default;
  245.    rtf_ptr=&rtf_default;
  246.    tabinitold[0]=tabinitnew[0]='\0';
  247.    Cformatting_char=formatting_char;
  248.    Cformatting_para=formatting_para;
  249.    tabstopsInit();
  250.    RTFInit();
  251.    read_code_file(codefile);        /* the file with the characters above 126
  252.                        files have the extension .code
  253.                        default file mac.code
  254.                        use flag -C for other files
  255.                         e.g ansi.code*/
  256.    open_land_file(landfile);        /* the file with the special WORD styles
  257.                        footer, footnote text, heading, ...
  258.                        files have the extension .land
  259.                        default file english.land
  260.                        use flag -L for other files
  261.                         e.g german.land    */
  262.    print_text(header_erwinbet,outfp);
  263.    output_str("\\documentstyle",'\0');
  264.    if(german_squotes || german_dquotes)
  265.        output_str("[german]",'\0');
  266.    output_str("{article}\n",'\0');
  267.    if(header_on)
  268.     {
  269.     output_str("\\pagestyle",'\0');
  270.     output_str("{myheadings}\n",'\0');
  271.     }
  272.    output_str("\\newlength{\\defaultparindent}\n",'\0');
  273.    output_str("\\setlength{\\defaultparindent}{\\parindent}\n",'\0');
  274.    default_read_font = RTFGetDestinationCallback(rtfFontTbl);
  275.  
  276.    (void)RTFSetClassCallback(rtfUnknown, UnknownClass);
  277.    (void)RTFSetClassCallback(rtfGroup, GroupClass);
  278.    (void)RTFSetClassCallback(rtfText, start_para);
  279.    (void)RTFSetClassCallback(rtfControl, ControlClass);
  280.    (void)RTFSetDestinationCallback(rtfPict, read_pict);
  281.  
  282.    RTFRead();
  283.  
  284.    if(rtf_group != 0) {
  285.       fprintf(stderr,"%s: End of file is in an unclosed RTF group (level %d)\n",
  286.           progname,rtf_group);
  287.    }
  288.    if(LaTeX_group != 0) {
  289.       fprintf(stderr,"%s: End of file is in an unclosed LaTeX group (level %d)\n",
  290.           progname,LaTeX_group);
  291.    }
  292.    if(quotecount % 2)
  293.    {
  294.       fprintf(stderr,"%s: Uneven number of quotes (%d) counted\n",
  295.           progname, quotecount);
  296.    }
  297.    if(fil != NULL) fclose(fil);
  298.    output_str("\\end{document}",'\0');
  299.    if (verbose)
  300.     fprintf(stderr,"\nIf there are any LaTeX errors or warnings,\n\
  301. have a look in the man page section troubleshooting \n\n");
  302.    return(0);
  303. }
  304. /*****************************************************************************
  305.  *
  306.  * Token class callbacks
  307.  */
  308. static void
  309. UnknownClass()
  310. {
  311.    fprintf(stderr,"%s: Unknown Token: %s\n",progname,rtfTextBuf);
  312. }
  313. /*****************************************************************************/
  314. static void
  315. GroupClass()
  316. {
  317.    switch (rtfMajor) {
  318.     case rtfBeginGroup:
  319.       if(initialised && !text_out) {
  320.      start_para();
  321.       }
  322.       if (!table_mode)        /*it's hard to know where the end of    */
  323.     end_table();          /*       a table is, maybe here           */
  324.       push_rtf_group();
  325.       rtf_group++;
  326.       break;
  327.     case rtfEndGroup:
  328.       if(--rtf_group == -1) {
  329.      fprintf(stderr,"%s: Unbalanced group\n", progname);
  330.       } else {
  331.      while(pop_LaTeX_stack()) continue;
  332.      pop_rtf_group();
  333.      if(end_of_par) {
  334.         end_para();
  335.      }
  336.       }
  337.       break;
  338.    }
  339. }
  340. static void
  341. initialise()
  342. {
  343.    inDefineStyle=TRUE;
  344.    DefineStyles();
  345.    inDefineStyle=FALSE;
  346.    if(pageno != 1) {
  347.       sprintf(buff,"\\setcounter{page}{%d}\n",pageno);
  348.       output_str(buff,'\0');
  349.    }
  350.    output_str("\n%*****************************************************************",'\0');
  351.    output_str("\n\\begin{document}\n",'\0');
  352.    tabstopsInit();
  353.    initialised = 1;            /* don't do it twice */
  354. }
  355. /*****************************************************************************/
  356. static void
  357. TextClass()
  358. {
  359.    output(rtfMajor,1);
  360. }
  361. /*****************************************************************************
  362.  *
  363.  * Process control symbol.
  364.  */
  365. static void
  366. ControlClass()
  367. {
  368.    switch (rtfMajor) {
  369.     case rtfVersion:
  370.       if(verbose) fprintf(stderr,"RTF version %d\n",rtfParam);
  371.       break;
  372.     case rtfDefFont:
  373.       default_font = rtfParam;        /* this may not be in the font table */
  374.       break;
  375.     case rtfCharSet:
  376.       CharSet ();
  377.       break;
  378.     case rtfDestination:
  379.       Destination();
  380.       break;
  381.     case rtfFontFamily:            /* only occurs within font table */
  382.       fprintf(stderr,"%s: You shouldn't see rtfFontType: minor %d\n",
  383.     progname,rtfMinor);
  384.       break;
  385.     case rtfColorName:            /* only occurs within color table */
  386.       fprintf(stderr,"%s: You shouldn't see rtfColorName: minor %d\n",
  387.     progname,rtfMinor);
  388.       break;
  389.     case rtfStyleAttr:            /* only occurs within stylesheet */
  390.       switch (rtfMinor) {
  391.        case rtfBasedOn:
  392.      if(rtfParam != rtfNoParam) {
  393.         static int count = 0;
  394.  
  395.         if(verbose > 1 || (verbose && count++ == 0)) {
  396.            msg_not_yet("sbasedon");
  397.         }
  398.      }
  399.      break;
  400.        case rtfNext:
  401.      if(rtfParam != rtfNoParam) {
  402.         static int count = 0;
  403.  
  404.         if(verbose > 1 || (verbose && count++ == 0)) {
  405.            msg_not_yet("snext");
  406.         }
  407.      }
  408.      break;
  409.        default:
  410.      fprintf(stderr,"%s: Illegal minor number for StyleAttr: %d\n",
  411.         progname,rtfMinor);
  412.      break;
  413.       }
  414.       break;
  415.     case rtfSpecialChar:
  416.       SpecialChar();
  417.       break;
  418.     case rtfDocAttr:
  419.       DocAttr();
  420.       break;
  421.     case rtfSectAttr:
  422.       SectAttr();
  423.       break;
  424.     case rtfTblAttr:
  425.       TblAttr();
  426.       break;
  427.     case rtfParAttr:
  428.       ParAttr();
  429.       break;
  430.     case rtfCharAttr:
  431.       if (Cformatting_char)
  432.           CharAttr();
  433.       break;
  434.     case rtfPictAttr:
  435.       fprintf(stderr,"%s: You shouldn't see rtfPictAttr: minor %d\n",
  436.     progname,rtfMinor);
  437.       break;
  438.     case rtfFieldAttr:
  439.       FieldAttr();
  440.       break;
  441.     case rtfTOCAttr:
  442.       TOCAttr();
  443.       break;
  444.     case rtfPosAttr:
  445.       PosAttr();
  446.       break;
  447.    }
  448. }
  449. /*****************************************************************************
  450.  *
  451.  * Control class major number handlers.  Each one switches on the
  452.  * minor numbers that occur within the major number.  rtfStyleSheet,
  453.  * rtfFontTbl, and rtfColorTbl are not in the switch because they're
  454.  * handled by the reader. rtfPict has its own callback.
  455.  */
  456. static void
  457. CharSet()
  458. {
  459.    switch (rtfMinor) {
  460.     case rtfAnsiCharSet:
  461.       break;
  462.     case rtfMacCharSet:
  463.       break;
  464.     case rtfPcCharSet:
  465.       break;
  466.     case rtfPcaCharSet:
  467.       break;
  468.    }
  469. }
  470. static void
  471. Destination()
  472. {
  473.    switch (rtfMinor) {
  474.     case rtfFootnote:
  475.       output_str("%\n",'\0');
  476.       output_str("\\footnote{",'\0');
  477.       push_LaTeX_stack("}%\n",Footnote,0);
  478.       break;
  479.     case rtfHeader:
  480.       if (!initialised)
  481.     initialise();
  482.       if (header_on)
  483.     {
  484.     output_str("\\markright{",'\0');
  485.     push_LaTeX_stack(" }\n",Header,0);
  486.     }
  487.       else
  488.     {
  489.     RTFSkipGroup();
  490.     RTFUngetToken();
  491.     }
  492.       break;
  493.     case rtfHeaderLeft:
  494.     case rtfHeaderRight:
  495.     case rtfHeaderFirst:
  496.       if (verbose)
  497.      msg_not_supported(rtfTextBuf+1);
  498.       break;
  499.     case rtfFooter:
  500.       if (header_on)
  501.     {
  502.     if (verbose)
  503.         fprintf(stderr,"LaTeX  supports only the header\n");
  504.     output_str("% LaTeX  supports only the header\n",'\0');
  505.     }
  506.     RTFSkipGroup();
  507.     RTFUngetToken();
  508.       break;
  509.     case rtfFooterLeft:
  510.       break;
  511.     case rtfFooterRight:
  512.       break;
  513.     case rtfFooterFirst:
  514.       break;
  515.     case rtfFNSep:
  516.       break;
  517.     case rtfFNContSep:
  518.       break;
  519.     case rtfFNContNotice:
  520.       break;
  521.     case rtfInfo:
  522.       break;
  523.     case rtfField:
  524.       break;
  525.     case rtfFieldInst:
  526.       {
  527.       char buf[80];
  528.       buf[0]='\0';
  529.       (void)RTFGetToken();
  530.       while(rtfClass==rtfText)
  531.     {
  532.     strcat(buf,rtfTextBuf);
  533.     (void)RTFGetToken();
  534.     }
  535.       RTFUngetToken();
  536.       if (strncmp(buf,"date",4)==0)
  537.     output_str("\\today",'\0');
  538.       else
  539.     if (verbose)
  540.        {
  541.        char msg_buf[80];
  542.        strcpy(msg_buf,rtfTextBuf+1);
  543.        strcat(msg_buf,buf);
  544.        msg_not_yet(msg_buf);
  545.        }
  546.       break;
  547.       }
  548.     break;
  549.     case rtfFieldResult:
  550.       break;
  551.     case rtfIndex:
  552.       break;
  553.     case rtfIndexBold:
  554.       break;
  555.     case rtfIndexItalic:
  556.       break;
  557.     case rtfIndexText:
  558.       break;
  559.     case rtfIndexRange:
  560.       break;
  561.     case rtfTOC:
  562.       break;
  563.     case rtfBookmarkStart:
  564.       break;
  565.     case rtfBookmarkEnd:
  566.       break;
  567.     case rtfITitle:
  568.     (void) RTFGetToken ();
  569.     while (rtfClass == rtfText)
  570.         (void) RTFGetToken ();
  571.     RTFUngetToken();
  572.       break;
  573.     case rtfISubject:
  574.     (void) RTFGetToken ();
  575.     while (rtfClass == rtfText)
  576.         (void) RTFGetToken ();
  577.     RTFUngetToken();
  578.        break;
  579.     case rtfIAuthor:
  580.     (void) RTFGetToken ();
  581.     while (rtfClass == rtfText)
  582.         (void) RTFGetToken ();
  583.     RTFUngetToken();
  584.       break;
  585.     case rtfIOperator:
  586.       break;
  587.     case rtfIKeywords:
  588.     (void) RTFGetToken ();
  589.     while (rtfClass == rtfText)
  590.         (void) RTFGetToken ();
  591.     RTFUngetToken();
  592.       break;
  593.     case rtfIComment:
  594.     (void) RTFGetToken ();
  595.     while (rtfClass == rtfText)
  596.         (void) RTFGetToken ();
  597.     RTFUngetToken();
  598.       break;
  599.     case rtfIVersion:
  600.       break;
  601.     case rtfIVerscomm:
  602. /* \verscomm is a token, made by Macintosh's WORD.
  603.  * I don't know the meaning,
  604.  * because it isn't specified in the RTF-specification.
  605.  */
  606.        RTFSkipGroup();
  607.        RTFUngetToken();
  608.        break;
  609.     case rtfIDoccomm:
  610.     (void) RTFGetToken ();
  611.     while (rtfClass == rtfText)
  612.         (void) RTFGetToken ();
  613.     RTFUngetToken();
  614.       break;
  615.    }
  616. }
  617. static void
  618. SpecialChar()
  619. {
  620.    switch (rtfMinor) {
  621.     case rtfCurHeadPage:
  622.       if (verbose && header_on)
  623.     fprintf(stderr,"LaTeX always puts the page number in right corner\n");
  624.       break;
  625.     case rtfCurFNote:
  626.       {
  627.       static int count=0;
  628.       if (verbose && count++ == 0)
  629.     msg_not_needed(rtfTextBuf+1);
  630.       break;
  631.       }
  632.     case rtfCurHeadPict:
  633.       msg_not_supported("chpict");
  634.       break;
  635.     case rtfCurHeadDate:
  636.     case rtfCurHeadTime:
  637.       if (verbose)
  638.      msg_not_supported(rtfTextBuf+1);
  639.       break;
  640.     case rtfFormula:
  641.       msg_not_yet("|");
  642.       break;
  643.     case rtfNoBrkSpace:
  644.       if(!text_out) start_para();
  645.       output_str("~",'\0');
  646.       break;
  647.     case rtfNoReqHyphen:
  648.       output_str("\\-",'\0');
  649.       break;
  650.     case rtfNoBrkHyphen:
  651.       if(!text_out) start_para();
  652.       output('-',1);
  653.       break;
  654.     case rtfPage:
  655.       end_para();
  656.       end_table();            /* if there is a table */
  657.       output_str("\n\\newpage\n",'\0');
  658.       break;
  659.     case rtfLine:
  660.       if (!other_linebreak)
  661.     output_str("\\\\ \n",'\0');
  662.       else
  663.           output_str(" \\hfill \\break \n",'\0');
  664.       break;
  665.     case rtfPar:
  666.       if (top_LaTeX_flags(Header))
  667.       {
  668.           if (!other_linebreak)
  669.           output_str("\\\\ \n",'\0');
  670.           else
  671.           output_str(" \\hfill \\break \n",'\0');
  672.       return;
  673.       }
  674.       if (top_LaTeX_flags(SpecialWORDstyle))
  675.       pop_LaTeX_stack();
  676.       if (tab==2 && text_out)
  677.       {
  678.       while (!top_LaTeX_flags(Tabstops) )
  679.          if (pop_LaTeX_stack()==0) break;
  680.       rtf_current=rtf_default;
  681.       output_str("\\\\ \n",'\0');
  682.       update_current();
  683.       }
  684.                         /* we may want to deal with this
  685.                        elsewhere, so as to pop the stacks
  686.                        before printing the newline */
  687.       RTFGetToken();
  688.       if(RTFCheckCM(rtfGroup,rtfEndGroup) ||
  689.      RTFCheckCMM(rtfControl,rtfParAttr,rtfParDef)) {
  690.      end_of_par = 1;
  691. /* Don't know if this one is needed anymore
  692.  *      } else if(in_table && RTFCheckCMM(rtfControl,rtfSpecialChar,rtfPar)) {
  693.  *     end_table();            * two \par's in a row *
  694.  */
  695.       } else {
  696.      end_para();
  697.       }
  698.       RTFUngetToken();
  699.       break;
  700.     case rtfSect:
  701.       rtfMinor = rtfPar;        /* pretend that it's just a para */
  702.       RTFUngetToken();
  703.       break;
  704.     case rtfTab:
  705.       if (top_LaTeX_flags(SpecialWORDstyle))
  706.     return;                /* no tab stops in header, haeding, ...*/
  707.       if(!text_out) start_para();
  708.       if (!tabstops_on)
  709.     break;
  710.       if (tab)
  711.      {
  712.      while (!top_LaTeX_flags(Tabstops) )
  713.         if (pop_LaTeX_stack()==0) break;
  714.      rtf_current=rtf_default;
  715.      output_str("\\> ",'\0');
  716.      update_current();
  717.      }
  718.       else
  719.      {
  720.      output(' ',1);
  721.      if (verbose && tabstops_on)
  722.         fprintf(stderr,"this tab stop is ignored\n   you have to specify the position of the tab stop before\n");
  723.      }
  724.       break;
  725.     case rtfCell:
  726.       while (!top_LaTeX_flags(Tabular) )
  727.     if (pop_LaTeX_stack()==0) break;
  728.       rtf_current=rtf_default;
  729.       cellnr++;
  730.       if (cellnr<max_cellnr)
  731.           output_str(" & ",'\0');
  732.       update_current();
  733.       break;
  734.     case rtfRow:
  735.       while (!top_LaTeX_flags(Tabular) )
  736.     if (pop_LaTeX_stack()==0) break;
  737.       rtf_current=rtf_default;
  738.       cellnr=0;
  739.       output_str("\\\\",'\0');
  740.       output('\n',1);
  741.       update_current();
  742.       break;
  743.     case rtfCurAnnot:
  744.       break;
  745.     case rtfAnnotation:
  746.       break;
  747.     case rtfAnnotID:
  748.       break;
  749.     case rtfCurAnnotRef:
  750.       break;
  751.     case rtfFNoteSep:
  752.       break;
  753.     case rtfFNoteCont:
  754.       break;
  755.     case rtfColumn:
  756.       break;
  757.     case rtfOptDest:
  758.       break;
  759.     case rtfIIntVersion:
  760.       break;
  761.     case rtfICreateTime:
  762.       break;
  763.     case rtfIRevisionTime:
  764.       break;
  765.     case rtfIPrintTime:
  766.       break;
  767.     case rtfIBackupTime:
  768.       break;
  769.     case rtfIEditTime:
  770.       break;
  771.     case rtfIYear:
  772.       break;
  773.     case rtfIMonth:
  774.       break;
  775.     case rtfIDay:
  776.       break;
  777.     case rtfIHour:
  778.       break;
  779.     case rtfIMinute:
  780.       break;
  781.     case rtfINPages:
  782.       break;
  783.     case rtfINWords:
  784.       break;
  785.     case rtfINChars:
  786.       break;
  787.     case rtfIIntID:
  788.       break;
  789.     case rtfBullet:
  790.       output_str("\\bullet ",'\0');
  791.       break;
  792.     case rtfEmDash:
  793.       output_str("---",'\0');
  794.       break;
  795.     case rtfEnDash:
  796.       output_str("--",'\0');
  797.       break;
  798.     case rtfLQuote:
  799.       if(german_squotes)
  800.      output_str("\\glq ",'\0');
  801.       else
  802.      output_str("`",'\0');
  803.       break;
  804.     case rtfRQuote:
  805.       if(german_squotes)
  806.      output_str("\\grq ",'\0');
  807.       else
  808.      output_str("'",'\0');
  809.       break;
  810.     case rtfLDblQuote:
  811.       if(german_dquotes)
  812.      output_str("\"`",'\0');
  813.       else
  814.      output_str("``",'\0');
  815.       break;
  816.     case rtfRDblQuote:
  817.       if(german_dquotes)
  818.      output_str("\"'",'\0');
  819.       else
  820.      output_str("''",'\0');
  821.       break;
  822.    }
  823. }
  824. static void
  825. DocAttr()
  826. {
  827.    switch (rtfMinor) {
  828.     case rtfPaperWidth:
  829.     case rtfPaperHeight:
  830.     case rtfLeftMargin:
  831.     case rtfRightMargin:
  832.     case rtfTopMargin:
  833.     case rtfBottomMargin:
  834.       {
  835.       static int count = 0;
  836.  
  837.       if(verbose > 1 || (verbose && count++ == 0)) {
  838.            msg_not_yet(rtfTextBuf+1);
  839.         }
  840.        }
  841.       break;
  842.     case rtfFacingPage:
  843.       if(verbose)
  844.            msg_not_yet(rtfTextBuf+1);
  845.        break;
  846.     case rtfGutterWid:
  847.       msg_not_yet("gutter");
  848.       break;
  849.     case rtfDefTab:
  850.       msg_not_yet("deftab");
  851.       break;
  852.     case rtfWidowCtrl:
  853.       msg_not_yet("widowctrl");
  854.       break;
  855.     case rtfFNoteEndSect:
  856.       msg_not_yet("endnotes");
  857.       break;
  858.     case rtfFNoteEndDoc:
  859.       break;
  860.     case rtfFNoteBottom:
  861.       break;
  862.     case rtfFNoteText:
  863.       msg_not_yet("ftntj");
  864.       break;
  865.     case rtfFNoteStart:
  866.       if(footnote_num0 != rtfParam) {
  867.      footnote_num0 = rtfParam;
  868.      change_headfoot = 1;
  869.       }
  870.       break;
  871.     case rtfFNoteRestart:
  872.       if(footnotes_restart_each_page != 1) {
  873.      footnotes_restart_each_page = 1;
  874.      change_headfoot = 1;
  875.       }
  876.       break;
  877.     case rtfHyphHotZone:
  878.       break;
  879.     case rtfPageStart:
  880.       pageno = rtfParam;
  881.       break;
  882.     case rtfLineStart:
  883.       lineno = rtfParam;
  884.       break;
  885.     case rtfLandscape:
  886.       msg_not_supported("landscape");
  887.       break;
  888.     case rtfFracWidth:
  889.       break;
  890.     case rtfNextFile:
  891.       break;
  892.     case rtfTemplate:
  893.       break;
  894.     case rtfMakeBackup:
  895.       break;
  896.     case rtfRTFDefault:
  897.       break;
  898.     case rtfRevisions:
  899.       break;
  900.     case rtfMirrorMargin:
  901.       break;
  902.     case rtfRevDisplay:
  903.       break;
  904.     case rtfRevBar:
  905.       break;
  906.    }
  907. }
  908. /*****************************************************************************/
  909.  
  910. static void
  911. SectAttr()
  912. {
  913.    switch (rtfMinor) {
  914.     case rtfSectDef:
  915.       set_headfoot_lines();
  916.       break;
  917.     case rtfNoBreak:
  918.       break;
  919.     case rtfColBreak:
  920.       break;
  921.     case rtfPageBreak:
  922.       break;
  923.     case rtfEvenBreak:
  924.       break;
  925.     case rtfOddBreak:
  926.       break;
  927.     case rtfPageStarts:
  928.       break;
  929.     case rtfPageCont:
  930.       break;
  931.     case rtfPageRestart:
  932.       break;
  933.     case rtfPageDecimal:
  934.       if(pageno_style != Pageno_Decimal) {
  935.      pageno_style = Pageno_Decimal;
  936.      change_headfoot = 1;
  937.       }
  938.       break;
  939.     case rtfPageURoman:
  940.       if(pageno_style != Pageno_URoman) {
  941.      pageno_style = Pageno_URoman;
  942.      change_headfoot = 1;
  943.       }
  944.       break;
  945.     case rtfPageLRoman:
  946.       if(pageno_style != Pageno_LRoman) {
  947.      pageno_style = Pageno_LRoman;
  948.      change_headfoot = 1;
  949.       }
  950.       break;
  951.     case rtfPageULetter:
  952.       msg_not_yet("pgnucltr");
  953.       break;
  954.     case rtfPageLLetter:
  955.       msg_not_yet("pgnlcltr");
  956.       break;
  957.     case rtfPageNumLeft:
  958.       if(pageno_x != rtfParam) {
  959.      pageno_x = rtfParam;
  960.      change_headfoot = 1;
  961.       }
  962.       break;
  963.     case rtfPageNumTop:
  964.       if(pageno_y != rtfParam) {
  965.      pageno_y = rtfParam;
  966.      change_headfoot = 1;
  967.       }
  968.       break;
  969.     case rtfLineModulus:
  970.       if(rtfParam != 0) msg_not_supported("linemod");
  971.       break;
  972.     case rtfLineStarts:
  973.       break;
  974.     case rtfLineDist:
  975.       msg_not_supported("linex");
  976.       break;
  977.     case rtfLineRestart:
  978.       msg_not_supported("linerestart");
  979.       break;
  980.     case rtfLineRestartPg:
  981.       msg_not_supported("lineppage");
  982.       break;
  983.     case rtfLineCont:
  984.       msg_not_supported("linecont");
  985.       break;
  986.     case rtfHeaderY:
  987.       msg_not_yet("headery");
  988.       break;
  989.     case rtfFooterY:
  990.       msg_not_yet("footery");
  991.       break;
  992.     case rtfTopVAlign:
  993.       break;
  994.     case rtfBottomVAlign:
  995.       break;
  996.     case rtfCenterVAlign:
  997.       break;
  998.     case rtfJustVAlign:
  999.       break;
  1000.     case rtfColumns:
  1001.       if(rtfParam != 1) msg_not_yet("cols");
  1002.       break;
  1003.     case rtfColumnLine:
  1004.       break;
  1005.     case rtfColumnSpace:
  1006.       msg_not_yet("colsx");
  1007.       break;
  1008.     case rtfENoteHere:
  1009.       msg_not_supported("endnhere");
  1010.       break;
  1011.     case rtfTitleSpecial:
  1012.       msg_not_supported("titlepg");
  1013.       break;
  1014.    }
  1015. }
  1016. static void
  1017. TblAttr()
  1018. {
  1019.    switch (rtfMinor) {
  1020.     case rtfCellBordBottom:
  1021.     case rtfCellBordTop:
  1022.     case rtfCellBordLeft:
  1023.     case rtfCellBordRight:
  1024.       {
  1025.       static int count = 0;
  1026.  
  1027.       if(verbose > 1 || (verbose && count++ == 0)) {
  1028.            msg_not_yet(rtfTextBuf+1);
  1029.         }
  1030.        }
  1031.       break;
  1032.     case rtfRowDef:
  1033.       table_mode=1;
  1034.       push_LaTeX_stack("",TabularInit,1);
  1035.       strcpy(tabinitnew,"\n\\begin{tabular}{");
  1036.       endOfLastCell=-70;
  1037.       max_cellnr=0;
  1038.       break;
  1039.     case rtfRowLeft:
  1040.     case rtfRowRight:
  1041.     case rtfRowCenter:
  1042.     case rtfRowGapH:
  1043.     case rtfRowHt:
  1044.     case rtfRowLeftEdge:
  1045.       {
  1046.       static int count = 0;
  1047.  
  1048.       if(verbose > 1 || (verbose && count++ == 0)) {
  1049.            msg_not_yet(rtfTextBuf+1);
  1050.         }
  1051.        }
  1052.       break;
  1053.     case rtfCellPos:
  1054.       {
  1055.       unsigned int cell_bright;
  1056.  
  1057.       max_cellnr++;
  1058.       cell_bright=(rtfParam-endOfLastCell)*smaller_cell_factor;
  1059.       sprintf(buff,"p{%gpt}",TW_TO_PT(cell_bright));
  1060.       strcat(tabinitnew,buff);
  1061.       endOfLastCell=rtfParam;
  1062.       break;
  1063.       }
  1064.     case rtfCellShading:
  1065. /* \clshdng is a token, made by Macintosh's WORD
  1066.  * I don't know the meaning,
  1067.  * because it isn't specified in the RTF-specification
  1068.  */
  1069.       break;
  1070.     case rtfMergeRngFirst:
  1071.       break;
  1072.     case rtfMergePrevious:
  1073.       break;
  1074.    }
  1075. }
  1076. /*****************************************************************************/
  1077. static void
  1078. ParAttr()
  1079. {
  1080.    switch (rtfMinor) {
  1081.     case rtfParDef:
  1082.       if(!initialised) {        /* it's hard to know where to call it*/
  1083.      initialise();
  1084.       }
  1085.       while(top_LaTeX_flags(Font) || top_LaTeX_flags(Font_Num) ||
  1086.         top_LaTeX_flags(Font_Size) || top_LaTeX_flags(Style) ||
  1087.         top_LaTeX_flags(Undefined) || top_LaTeX_flags(Underline) ||
  1088.         top_LaTeX_flags(Sub_Super) ||
  1089.         top_LaTeX_flags(Paragraph) ||
  1090.         top_LaTeX_flags(NormalWORDstyle) ||
  1091.         top_LaTeX_flags(LRskip) || top_LaTeX_flags(SpecialWORDstyle)) {
  1092.      (void)pop_LaTeX_stack();
  1093.       }
  1094.       rtf_current.par_attr.leftskip=rtf_current.par_attr.rightskip=0;
  1095.       if (top_LaTeX_flags(Tabstops))
  1096.     {
  1097.      (void)pop_LaTeX_stack();
  1098.     Cformatting_char=formatting_char;
  1099.     Cformatting_para=formatting_para;
  1100.     }
  1101.       if (!table_mode && top_LaTeX_flags(Tabular))
  1102.     end_table();                  /* it's hard to know where to call it*/
  1103.       if ((table_mode) &&               /* begin of a table in rtf */
  1104.         top_LaTeX_flags(TabularInit)  )
  1105.      if (strcmp(tabinitold,tabinitnew)==0)
  1106.         {                          /*we haven't finished the last */
  1107.         (void)pop_LaTeX_stack();   /* table in LaTeX and the parameters */
  1108.         }                          /* of both the current and last      */
  1109.                        /* rtf-table are equal so we needn't */
  1110.                        /* start a new LaTeX-table      */
  1111.      else
  1112.         {
  1113.         end_table();         /* we will have to finish the last table, if there is one  */
  1114.         strcpy(tabinitold,tabinitnew);
  1115.         table_mode=1;
  1116.         output_str(tabinitnew,'\0'); /* and to start a new one */
  1117.         output_str("}\n",'\0');
  1118.         push_LaTeX_stack("\\end{tabular}\n",Tabular,0);
  1119.         Cformatting_char=formatting_char&&formatting_table;
  1120.         Cformatting_para=formatting_para&&formatting_table;
  1121.         }
  1122.       if(end_of_par /*&& !table_mode*/) {
  1123.      end_para();
  1124.       }
  1125.       ntabs = 0;
  1126.       table_mode=0;
  1127.       tab=0;
  1128.       rtf_default.LaTeX_stack = rtf_ptr->LaTeX_stack;
  1129.       rtf_default.prev = rtf_ptr->prev;
  1130.       *rtf_ptr = rtf_default;
  1131.       rtf_current.char_attr = rtf_default.char_attr;
  1132.       (void)RTFSetClassCallback(rtfText, start_para); /* not really start a new pragraph
  1133.                              but have a look if there is a
  1134.                              table end */
  1135.       break;
  1136.     case rtfStyleNum:
  1137.       if(inDefineStyle)
  1138.      RTFExpandStyle(rtfParam);
  1139.       else
  1140.      {
  1141.      if(!initialised)
  1142.          {        /* it's hard to know where to call it*/
  1143.  
  1144.          RTFUngetToken();   /* store the Token, because initialise  */
  1145.          initialise();      /* changes it                           */
  1146.          RTFGetToken();
  1147.          }
  1148.      if (!table_mode && top_LaTeX_flags(Tabular))
  1149.         end_table();                  /* it's hard to know where to call it*/
  1150.      setstylecommand(rtfParam);
  1151.      }
  1152.       break;
  1153.     case rtfQuadLeft:
  1154.       {
  1155.      static int count = 0;
  1156.  
  1157.      if(verbose > 1 || (verbose && count++ == 0)) {
  1158.         msg_map_to("gl","gj");
  1159.      }
  1160.      rtf_ptr->par_attr.flags |= LeftAlign;
  1161.       }
  1162.       break;
  1163.     case rtfQuadRight:
  1164.       if (text_out)
  1165.     {
  1166.         if (!Cformatting_para)                /* no paragraph formatting */
  1167.         break;
  1168.     output_str("\n\\begin{flushright}",'\0');
  1169.     push_LaTeX_stack("\n\\end{flushright}",Paragraph,0);
  1170.     }
  1171.       else
  1172.     rtf_ptr->par_attr.flags |= RightAlign;
  1173.       break;
  1174.     case rtfQuadJust:
  1175.       rtf_ptr->par_attr.flags &= ~(LeftAlign | Centred | RightAlign);
  1176.       break;
  1177.     case rtfQuadCenter:
  1178.       if (text_out)
  1179.     {
  1180.         if (!Cformatting_para)                /* no paragraph formatting */
  1181.         break;
  1182.     output_str("\n\\begin{center}",'\0');
  1183.     push_LaTeX_stack("\n\\end{center}",Paragraph,0);
  1184.     }
  1185.       else
  1186.     rtf_ptr->par_attr.flags |= Centred;
  1187.       break;
  1188.     case rtfFirstIndent:
  1189.       rtf_ptr->par_attr.parindent = rtfParam;
  1190.       break;
  1191.     case rtfLeftIndent:
  1192.       rtf_ptr->par_attr.leftskip = rtfParam;
  1193.       break;
  1194.     case rtfRightIndent:
  1195.       rtf_ptr->par_attr.rightskip = rtfParam;
  1196.       break;
  1197.     case rtfSpaceBefore:
  1198.       rtf_ptr->par_attr.skip_before = rtfParam;
  1199.       break;
  1200.     case rtfSpaceAfter:
  1201.       rtf_ptr->par_attr.skip_after = rtfParam;
  1202.       break;
  1203.     case rtfSpaceBetween:
  1204.       break;
  1205.     case rtfInTable:
  1206.       table_mode=1;
  1207.       break;
  1208.     case rtfKeep:
  1209.       break;
  1210.     case rtfKeepNext:
  1211.       break;
  1212.     case rtfSideBySide:
  1213.       break;
  1214.     case rtfPBBefore:
  1215.       break;
  1216.     case rtfNoLineNum:            /* ignored */
  1217.       break;
  1218.     case rtfBorderTop:
  1219.       break;
  1220.     case rtfBorderBottom:
  1221.       break;
  1222.     case rtfBorderLeft:
  1223.       break;
  1224.     case rtfBorderRight:
  1225.       break;
  1226.     case rtfBorderBar:
  1227.       break;
  1228.     case rtfBorderBox:
  1229.       break;
  1230.     case rtfBorderBetween:
  1231.       break;
  1232.     case rtfBorderSingle:
  1233.       break;
  1234.     case rtfBorderThick:
  1235.       break;
  1236.     case rtfBorderShadow:
  1237.       break;
  1238.     case rtfBorderDouble:
  1239.       break;
  1240.     case rtfBorderDot:
  1241.       break;
  1242.     case rtfBorderHair:
  1243.       break;
  1244.     case rtfBorderSpace:
  1245.       break;
  1246.     case rtfTabPos:
  1247.       if (top_LaTeX_flags(SpecialWORDstyle))
  1248.     return;                /*no tab stops in header, heading, ...*/
  1249.       if (!tabstops_on)
  1250.     break;
  1251.       if (!table_mode && top_LaTeX_flags(Tabular))
  1252.     end_table();
  1253.       if (table_mode)
  1254.     {
  1255.     if (verbose)
  1256.         fprintf(stderr,"can't deal with tab stops in tables");
  1257.     }
  1258.       else
  1259.     {
  1260.     tab=1;
  1261.     if(ntabs >= NTABS) {
  1262.         if(ntabs == NTABS)
  1263.             fprintf(stderr,"%s: Attempt to set more than %d tabs\n",
  1264.                 progname,NTABS);
  1265.     } else {
  1266.         tabstops[ntabs++].pos = rtfParam;
  1267.         tabstops[ntabs].type = TabLeft;
  1268.     }
  1269.       }
  1270.       break;
  1271.     case rtfTabRight:
  1272.       if(ntabs < NTABS) {
  1273.      tabstops[ntabs].type = TabRight;
  1274.       }
  1275.       break;
  1276.     case rtfTabCenter:
  1277.       if(ntabs < NTABS) {
  1278.      tabstops[ntabs].type = TabCentre;
  1279.       }
  1280.       break;
  1281.     case rtfTabDecimal:
  1282.       if(ntabs < NTABS) {
  1283.      tabstops[ntabs].type = TabDecimal;
  1284.       }
  1285.       break;
  1286.     case rtfTabBar:
  1287.       {
  1288.      static int count = 0;
  1289.  
  1290.      if(verbose > 1 || (verbose && count++ == 0))
  1291.        msg_not_yet("tb");
  1292.       }
  1293.       break;
  1294.     case rtfLeaderDot:
  1295.       break;
  1296.     case rtfLeaderHyphen:
  1297.       break;
  1298.     case rtfLeaderUnder:
  1299.       break;
  1300.     case rtfLeaderThick:
  1301.       break;
  1302.    }
  1303. }
  1304. /*procedure not needed yet*/
  1305. static void PictAttr ()
  1306. {
  1307.    switch (rtfMinor) {
  1308.     case rtfMacQD:
  1309.       break;
  1310.     case rtfWinMetafile:
  1311.       break;
  1312.     case rtfWinBitmap:
  1313.       break;
  1314.     case rtfPicWid:
  1315.       break;
  1316.     case rtfPicHt:
  1317.       break;
  1318.     case rtfPicGoalWid:
  1319.       break;
  1320.     case rtfPicGoalHt:
  1321.       break;
  1322.     case rtfPicScaleX:
  1323.       break;
  1324.     case rtfPicScaleY:
  1325.       break;
  1326.     case rtfPicScaled:
  1327.       break;
  1328.     case rtfPicCropTop:
  1329.       break;
  1330.     case rtfPicCropBottom:
  1331.       break;
  1332.     case rtfPicCropLeft:
  1333.       break;
  1334.     case rtfPicCropRight:
  1335.       break;
  1336.     case rtfPixelBits:
  1337.       break;
  1338.     case rtfBitmapPlanes:
  1339.       break;
  1340.     case rtfBitmapWid:
  1341.       break;
  1342.     case rtfPicBinary:
  1343.       break;
  1344.    }
  1345. }
  1346. /*****************************************************************************/
  1347. static void
  1348. FieldAttr()
  1349. {
  1350.    switch (rtfMinor) {
  1351.     case rtfFieldDirty:
  1352.       break;
  1353.     case rtfFieldEdited:
  1354.       break;
  1355.     case rtfFieldLocked:
  1356.       break;
  1357.     case rtfFieldPrivate:
  1358.       break;
  1359.    }
  1360. }
  1361. /*****************************************************************************/
  1362. static void
  1363. TOCAttr()
  1364. {
  1365.    switch (rtfMinor) {
  1366.     case rtfTOCType:
  1367.       break;
  1368.     case rtfTOCLevel:
  1369.       break;
  1370.    }
  1371. }
  1372. /*****************************************************************************/
  1373. static void
  1374. PosAttr()
  1375. {
  1376.    switch (rtfMinor) {
  1377.     case rtfPosX:
  1378.       break;
  1379.     case rtfPosXCenter:
  1380.       break;
  1381.     case rtfPosXInside:
  1382.       break;
  1383.     case rtfPosXLeft:
  1384.       break;
  1385.     case rtfPosXOutSide:
  1386.       break;
  1387.     case rtfPosXRight:
  1388.       break;
  1389.     case rtfPosY:
  1390.       break;
  1391.     case rtfPosYInline:
  1392.       break;
  1393.     case rtfPosYTop:
  1394.       break;
  1395.     case rtfPosYCenter:
  1396.       break;
  1397.     case rtfPosYBottom:
  1398.       break;
  1399.     case rtfAbsWid:
  1400.       break;
  1401.     case rtfTextDist:
  1402.       break;
  1403.     case rtfRPosMargV:
  1404.       break;
  1405.     case rtfRPosPageV:
  1406.       break;
  1407.     case rtfRPosMargH:
  1408.       break;
  1409.     case rtfRPosPageH:
  1410.       break;
  1411.     case rtfRPosColH:
  1412.       break;
  1413.    }
  1414. }
  1415. /*****************************************************************************
  1416.  *
  1417.  * Deal with Pict destinations
  1418.  */
  1419. static void
  1420. read_pict()
  1421. {
  1422. static int count=0;
  1423. if (verbose && count++==0)
  1424.     fprintf(stderr,"%s: Don't support any picture-things yet; be patient\n",
  1425.     progname);
  1426. if (verbose>1)
  1427.     msg_not_yet(rtfTextBuf+1);
  1428.     RTFSkipGroup ();
  1429.     RTFRouteToken ();       /* feed "}" back to router */
  1430.  
  1431. }
  1432. /*****************************************************************************
  1433.  *
  1434.  * Deal with things like footnote numbering and page numbers; things
  1435.  * that involve the headline or footline
  1436.  */
  1437. static void
  1438. set_headfoot_lines()
  1439. {
  1440.    int pageno_top = (pageno_y < paper_height/2 ? 1 : 0);
  1441.    if(!change_headfoot) return;
  1442. # ifdef notdef /* I think this is left over from rtf2tex */
  1443. /*
  1444.  * The headline first
  1445.  *
  1446.    output_str("\\headline={\\tenrm ",'\0');
  1447.    if(footnotes_restart_each_page) {
  1448.       sprintf(buff,"\\footnum=%d",footnote_num0);
  1449.       output_str(buff,' ');
  1450.  }
  1451.    if(pageno_top) {
  1452.       sprintf(buff,"\\kern %gpt %s\\hfil",TW_TO_PT(pageno_x),page_num());
  1453.       output_str(buff,' ');
  1454.    }
  1455.    output_str("}",'\n');
  1456. /*
  1457.  * And now the foot
  1458.  *
  1459.    output_str("\\footline={\\tenrm ",'\0');
  1460.    if(!pageno_top) {
  1461.       sprintf(buff,"\\kern %gpt %s\\hfil",TW_TO_PT(pageno_x),page_num());
  1462.       output_str(buff,' ');
  1463.    }
  1464.    output_str("}",'\n');
  1465.    change_headfoot = 0;            /* we've done it *
  1466. */
  1467. # endif /* notdef */
  1468. }
  1469. /*****************************************************************************
  1470.  *
  1471.  * Convert the pageno to the desired form
  1472.  */
  1473. static char *
  1474. page_num()
  1475. {
  1476.    switch (pageno_style) {
  1477.     case Pageno_Decimal:
  1478.       return("\\number\\pageno");
  1479.     case Pageno_LRoman:
  1480.       return("\\romannumeral\\pageno");
  1481.     case Pageno_URoman:
  1482.       return("\\uppercase\\expandafter{\\romannumeral\\pageno}");
  1483.     default:
  1484.       return("");
  1485.    }
  1486. }
  1487. /*****************************************************************************
  1488.  *
  1489.  * This is called when we see the first text token after each \par
  1490.  */
  1491. #define CURRENT(WHAT)            /* is WHAT up-to-date? */ \
  1492.    (rtf_current.WHAT == rtf_ptr->WHAT)
  1493. static void
  1494. start_para()
  1495. {
  1496.    if(!initialised) {            /* this could be the place */
  1497.       initialise();
  1498.    }
  1499.  
  1500.    if(!table_mode && top_LaTeX_flags(Tabular))
  1501.         end_table();
  1502.    if (tab==1 && !table_mode)
  1503.     start_tabstops();
  1504.    update_current();
  1505.     text_out = 1;
  1506.     (void)RTFSetClassCallback(rtfText, TextClass);
  1507.     if(rtfClass == rtfText) {
  1508.         RTFUngetToken();            /* re-schedule the text */
  1509.    }
  1510. }
  1511. /*
  1512.  * End a paragraph
  1513.  */
  1514. static void
  1515. end_para()
  1516. {
  1517.    if(in_table) {
  1518.       tab_num = 0;
  1519.    } else {
  1520.       if (top_LaTeX_flags(SpecialWORDstyle) || top_LaTeX_flags(Header))
  1521.     pop_LaTeX_stack();
  1522.       output('\n',1);
  1523.       output('\n',1);
  1524.       }
  1525.    text_out = 0;
  1526.    end_of_par = 0;
  1527.    (void)RTFSetClassCallback(rtfText, start_para);
  1528. }
  1529. /*****************************************************************************
  1530.  *
  1531.  * Force an update of the current state, only emitting commands
  1532.  * that actually change anything.
  1533.  */
  1534. static void
  1535. update_current()
  1536. {
  1537.    RTFStyle *style;
  1538.  
  1539. if (Cformatting_char)
  1540. {
  1541.    if(!CURRENT(char_attr.FontSize))
  1542.       set_fontsize(rtf_ptr->char_attr.FontSize);
  1543.    if(!CURRENT(char_attr.sub_super_height))
  1544.       set_subsuper(rtf_ptr->char_attr.sub_super_height);
  1545.    if(!CURRENT(char_attr.smallcaps))
  1546.       set_smallcaps();
  1547.    if(!CURRENT(char_attr.font))
  1548.    if(rtf_ptr->char_attr.font == Bold) {
  1549.     if (initialised)
  1550.           set_font(Bold,1,"\n{\\bf ","}");
  1551.     else
  1552.           set_font(Bold,1,"\n\\bf ","");
  1553.    }
  1554.    if(!CURRENT(char_attr.font))
  1555.    if(rtf_ptr->char_attr.font == Italic) {
  1556.     if (initialised)
  1557.           set_font(Italic,1,"\n{\\it ","}");
  1558.     else
  1559.           set_font(Italic,1,"\n\\it ","");
  1560.    }
  1561. }
  1562. if (Cformatting_para)
  1563. {
  1564.    if(!CURRENT(par_attr.flags))
  1565.     switch (rtf_ptr->par_attr.flags)
  1566.       {
  1567.       case Centred:
  1568.         output_str("\n\\begin{center}",'\0');
  1569.         push_LaTeX_stack("\n\\end{center}",Paragraph,0);
  1570.         break;
  1571.       case RightAlign:
  1572.         output_str("\n\\begin{flushright}",'\0');
  1573.         push_LaTeX_stack("\n\\end{flushright}",Paragraph,0);
  1574.         break;
  1575.       case LeftAlign:
  1576.         output_str("\n\\begin{flushleft}",'\0');
  1577.         push_LaTeX_stack("\n\\end{flushleft}",Paragraph,0);
  1578.         break;
  1579.       default:                 /* block modus (LaTeX default)*/
  1580.         break;
  1581.   }
  1582.    if(!CURRENT(par_attr.parindent))
  1583.     {
  1584.     if (rtf_ptr->par_attr.parindent==LaTeXdefault)
  1585.         sprintf(buff,"\n\\setlength{\\parindent}{\\defaultparindent}");
  1586.     else
  1587.         sprintf(buff,"\n\\setlength{\\parindent}{%gpt}",
  1588.              TW_TO_PT(rtf_ptr->par_attr.parindent));
  1589.     output_str(buff,'\0');
  1590.     }
  1591.    if (!CURRENT(par_attr.skip_before) ||
  1592.        !CURRENT(par_attr.skip_after))
  1593.     {
  1594.     int skip;
  1595.  
  1596.     skip=rtf_ptr->par_attr.skip_after+rtf_ptr->par_attr.skip_before;
  1597.     sprintf(buff,"\n\\setlength{\\parskip}{%gpt}",
  1598.          TW_TO_PT(skip));
  1599.     output_str(buff,'\0');
  1600.     }
  1601.    if((!CURRENT(par_attr.leftskip) || !CURRENT(par_attr.rightskip)) &&
  1602.        rl_skip_on)
  1603.     {
  1604.     if ((rtf_ptr->par_attr.leftskip!=0) ||
  1605.         (rtf_ptr->par_attr.rightskip!=0) )
  1606.         {
  1607.         output_str("\n\\begin{list}",'\0');
  1608.         output_str("{ }{",'\0');
  1609.         sprintf(buff,"\n\\setlength{\\leftmargin}{%gpt}",
  1610.              TW_TO_PT(rtf_ptr->par_attr.leftskip));
  1611.         output_str(buff,'\0');
  1612.         sprintf(buff,"\\setlength{\\rightmargin}{%gpt}",
  1613.              TW_TO_PT(rtf_ptr->par_attr.rightskip));
  1614.         output_str(buff,'\0');
  1615.         output_str("\n\\setlength{\\topsep}{0pt}",'\0');
  1616.         output_str("\\setlength{\\partopsep}{0pt}",'\0');
  1617.         output_str("}\n\\item ",'\0');
  1618.         push_LaTeX_stack("\n\\end{list}",LRskip,0);
  1619.         }
  1620.     }
  1621.  
  1622. }
  1623.    rtf_current = *rtf_ptr;
  1624.    rtf_current.LaTeX_stack = NULL;
  1625.    rtf_current.prev = NULL;
  1626. }
  1627. /*****************************************************************************
  1628.  *
  1629.  * ALLDONE
  1630.  */
  1631.  
  1632. #define SET_FONT(FONT,START,END)    /* set a Font */\
  1633.   if(text_out && initialised) { \
  1634.      set_font(FONT,(rtfParam == 0 ? 0 : 1),START,END); \
  1635.   } \
  1636.   rtf_ptr->char_attr.font = (rtfParam == 0 ? 0 : FONT);
  1637. #define SET_FONTSIZE(FONTSIZE)    /* set a Fontsize */\
  1638.   if(text_out && initialised) { \
  1639.      set_fontsize(FONTSIZE); \
  1640.   } \
  1641.   rtf_ptr->char_attr.FontSize = FONTSIZE;
  1642.  
  1643.  
  1644. static void
  1645. CharAttr()
  1646. {
  1647.    switch (rtfMinor) {
  1648.     case rtfPlain:
  1649.       if(text_out) {
  1650.          while(top_LaTeX_flags(Underline) || top_LaTeX_flags(Sub_Super)
  1651.         || top_LaTeX_flags(Font) || top_LaTeX_flags(Font_Num))
  1652.         (void)pop_LaTeX_stack();
  1653.       }
  1654.       rtf_ptr->char_attr = rtf_default.char_attr;
  1655.       rtf_current.char_attr = rtf_default.char_attr;
  1656.       break;
  1657.     case rtfBold:
  1658.       SET_FONT(Bold,"\n{\\bf ","}");
  1659.       break;
  1660.     case rtfItalic:
  1661.       SET_FONT(Italic,"\n{\\it ","}");
  1662.       break;
  1663.     case rtfAllCaps:
  1664.        {
  1665.        static int count;
  1666.      if(verbose > 1 || (verbose && count++ == 0)) {
  1667.             msg_map_to("ac","sc");
  1668.          }
  1669.        }
  1670.     case rtfSmallCaps:
  1671.      if(text_out && initialised)
  1672.     set_smallcaps();
  1673.      rtf_ptr->char_attr.smallcaps = 1;
  1674.       break;
  1675.     case rtfStrikeThru:
  1676.     case rtfOutline:
  1677.     case rtfShadow:
  1678.     case rtfInvisible:
  1679.       {
  1680.      static int count = 0;
  1681.  
  1682.      if(verbose > 1 || (verbose && count == 0))
  1683.        msg_not_supported(
  1684.                  rtfMinor == rtfStrikeThru ? "strike" :
  1685.                  rtfMinor == rtfOutline ? "outl" :
  1686.                  rtfMinor == rtfShadow ? "shad" :
  1687.                  rtfMinor == rtfInvisible ? "v" : "Unknown");
  1688.      count++;
  1689.       }
  1690.       break;
  1691.     case rtfFontNum:
  1692.       break;
  1693.     case rtfFontSize:
  1694.       SET_FONTSIZE(rtfParam/2);
  1695.       break;
  1696.     case rtfDbUnderline:
  1697.     case rtfDUnderline:
  1698.       if (!noUnderline)
  1699.       {
  1700.     if (initialised)
  1701.      {
  1702.      output_str("\n\\underline{\\underline{",'\0');
  1703.      push_LaTeX_stack("}}",Underline,0);
  1704.      }
  1705. /*    else         doesn't work in LaTeX
  1706.      {
  1707.      output_str("\n\\underline \\bgroup \\underline \\bgroup",'\0');
  1708.      push_LaTeX_stack("\\egroup \\egroup",Underline,0);
  1709.      }
  1710. */
  1711.     break;
  1712.       }
  1713.     case rtfUnderline:
  1714.     case rtfWUnderline:
  1715.       {
  1716.      static int count = 0;
  1717.  
  1718.      if (!noUnderline)
  1719.      {
  1720.         if (initialised)
  1721.         {
  1722.         output_str("\n\\underline{",'\0');
  1723.         push_LaTeX_stack("}",Underline,0);
  1724.         }
  1725. /*        else     doesn't work in LaTeX
  1726.         {
  1727.         output_str("\n\\underline \\bgroup",'\0');
  1728.         push_LaTeX_stack("\\egroup",Underline,0);
  1729.         }
  1730. */
  1731.      }
  1732.      else
  1733.      {
  1734.          if(verbose > 1 || (verbose && count++ == 0)) {
  1735.             msg_map_to((rtfMinor == rtfUnderline ? "ul" : "ulw"),"i");
  1736.          }
  1737.         rtfMinor = rtfItalic;
  1738.         CharAttr();
  1739.      }
  1740.       }
  1741.       break;
  1742.     case rtfNoUnderline:
  1743.       break;
  1744.     case rtfSubScript:
  1745.     case rtfSuperScript:
  1746.       if(rtf_ptr->char_attr.sub_super_height == rtfParam) break;
  1747.       if(!text_out && initialised) start_para();
  1748.   if(text_out && initialised) {
  1749.      set_subsuper(rtfParam);
  1750.   }
  1751.   rtf_ptr->char_attr.sub_super_height = rtfParam;
  1752.   break;
  1753.     case rtfForeColor:
  1754.       msg_not_supported("cf");
  1755.       break;
  1756.     case rtfBackColor:
  1757.       break;
  1758.     case rtfExpand:
  1759.       msg_not_needed("expnd");
  1760.       break;
  1761.     case rtfRevised:
  1762.       break;
  1763.    }
  1764. }
  1765.  
  1766. /*****************************************************************************
  1767.  *
  1768.  * Various ways of refusing to deal with a keyword
  1769.  *
  1770.  *
  1771.  * Treat \from as \to (e.g. treat \ul as \i)
  1772.  */
  1773. static void
  1774. msg_map_to(from,to)
  1775. char *from, *to;
  1776. {
  1777.    if(verbose && !writing_defs) {
  1778.       fprintf(stderr,"I'm going to treat \\%s as \\%s\n",from,to);
  1779.    }
  1780. }
  1781. /*
  1782.  * Keyword is neither needed by LaTeX or supported by rtf2LaTeX
  1783.  * For example, \expnd to fiddle with inter-character spacing.
  1784.  */
  1785.  
  1786. static void
  1787. msg_not_needed(name)
  1788. char *name;
  1789. {
  1790.    if(verbose && !writing_defs) {
  1791.       fprintf(stderr,"\\%s is neither needed nor supported\n",name);
  1792.    }
  1793. }
  1794. /*
  1795.  * Keyword isn't supported, and probably can't be
  1796.  * For example, \cf to change colours
  1797.  */
  1798. static void
  1799. msg_not_supported(name)
  1800. char *name;
  1801. {
  1802.    static int pointer = 0;
  1803.    for (pointer=0;(name[pointer]!='\0' && isalpha(name[pointer]));pointer++)
  1804.       continue;
  1805.    /* Should fix problem writing to string constants with gcc */
  1806.    if(name[pointer] != '\0')
  1807.       name[pointer]='\0';         /*No argument will be printed*/
  1808.    if(verbose && !writing_defs) {
  1809.       fprintf(stderr,"%s: Don't support \\%s; sorry\n",progname,name);
  1810.    }
  1811. }
  1812. /*
  1813.  * Keyword will be supported, but I haven't done it yet
  1814.  */
  1815. static void
  1816. msg_not_yet(name)
  1817. char *name;
  1818. {
  1819.    if(verbose && !writing_defs) {
  1820.       fprintf(stderr,"%s: Don't support \\%s yet; be patient\n",progname,name);
  1821.    }
  1822. }
  1823.  
  1824.  
  1825.  
  1826.  
  1827. /*****************************************************************************
  1828.  *
  1829.  * Convert a string to a form that LaTeX can handle
  1830.  *
  1831.  * Remove spaces and capitalise the following letter,
  1832.  * and converted digits to letters (1 --> A etc., 0 --> O)
  1833.  */
  1834. static char *
  1835. LaTeX_name(str)
  1836. char *str;
  1837. {
  1838.    static char temp[50];
  1839.    char *ptr;
  1840.  
  1841.    for(ptr = temp;*str != '\0';str++) {
  1842.       if(isspace(*str)) {
  1843.      for(str++;isspace(*str);str++) continue;
  1844.      if(*str == '\0') break;
  1845.      *str = islower(*str) ? toupper(*str) : *str;
  1846.      str--; continue;        /* reprocess the character */
  1847.       } else if(isdigit(*str)) {
  1848.      if(*str == '0') *ptr++ = 'O';
  1849.      else *ptr++ = *str + 'A' - '1';
  1850.       } else {
  1851.      *ptr++ = *str;
  1852.       }
  1853.    }
  1854.    *ptr = '\0';
  1855.  
  1856.    return(temp);
  1857. }
  1858.  
  1859. /*****************************************************************************/
  1860.  
  1861. static void
  1862. usage()
  1863. {
  1864.    static char *msg[] = {
  1865.       "Your options are:",
  1866.       "       -c      No character formatting stuff",
  1867.       "       -C file Use another translation-file for characters above 128",
  1868.       "       -d      Use WORD formates within special WORD styles ",
  1869.       "               like heading, footnote text, ...",
  1870.       "       -H      Use LaTeX header and footer, not as default WORD header",
  1871.       "       -h      This message",
  1872.       "       -L file Use another translation-file for specilal WORD styles",
  1873.       "               like heading, footer, footnote text, ...",
  1874.       "       -n      Use \\hfill instead of \\\\ for making a new line",
  1875.       "       -o file Output to file",
  1876.       "       -p      No paragraph formatting stuff",
  1877.       "       -r      No left or right skip",
  1878.       #ifdef __riscos
  1879.       "       -R path Path (or variable) pointing to the code and land directories",
  1880.       #endif
  1881.       "       -s      No tab stops",
  1882.       "       -t      No formatting in tables",
  1883.       "       -T f    Decrease-factor for the cell-width (default:0.7)",
  1884.       "       -u      Change underline to italic",
  1885.       "       -v[#]   Turn on verbose messages; the higher #, the more messages",
  1886.       "       -V      Print the version number",
  1887.       "If you omit the filename rtf2LaTeX will read standard input.",
  1888.       "\nIf there are any LaTeX errors or warnings,",
  1889.       "have a look in the man page section troubleshooting.\n ",
  1890.       NULL,
  1891.    };
  1892.  
  1893.    fprintf(stderr, "Usage: %s [options] [RTF-file]\n", progname);
  1894.    print_text(msg,stderr);
  1895. }
  1896.  
  1897. /*****************************************************************************
  1898.  *
  1899.  * print some text MSG to a stream FIL
  1900.  */
  1901. static void
  1902. print_text(msg,fil)
  1903. char *msg[];
  1904. FILE *fil;
  1905. {
  1906.    char **line;
  1907.  
  1908.    for(line = msg;*line != NULL;line++) {
  1909.       fprintf(fil,"%s\n",*line);
  1910.    }
  1911. }
  1912.  
  1913. /*****************************************************************************
  1914.  *
  1915.  * set a Font
  1916.  */
  1917. static void
  1918. set_font(font,turn_on,start,end)
  1919. int font;                /* flag for font to set (e.g. Bold) */
  1920. int turn_on;                /* should I start the font or end it?*/
  1921. char *end;                /* strings to start and */
  1922. char *start;                /* end the group that sets the font */
  1923. {
  1924.    if(turn_on && Cformatting_char) {
  1925.      if(!no_grouping) {
  1926.         push_LaTeX_stack(end,Font,font);
  1927.      }
  1928.      output_str(start,'\0');
  1929.    }
  1930. }
  1931.  
  1932. /*****************************************************************************
  1933.  *
  1934.  * change fontsize
  1935.  */
  1936. void set_fontsize(fontsize)
  1937. int fontsize;                /* size of fonts default 10 */
  1938. {
  1939. if (fontsize<0)
  1940.     {
  1941.     p6("set_fontsize\nfontsize<0");
  1942.     return;
  1943.     }
  1944. if (fontsize==0)
  1945.     {
  1946.     p6("set_fontsize\nfontsize==0");
  1947.     return;
  1948.     }
  1949. if (!Cformatting_char)
  1950.     {
  1951.     return;
  1952.     }
  1953. if (fontsize==8)
  1954.     {
  1955.     (void)RTFGetToken();
  1956.     if (strcmp(rtfTextBuf,"\\up6")==0)
  1957.         {
  1958.         RTFUngetToken();
  1959.         return;            /* mostly we are before a footnote here */
  1960.         }                       /* so we need no size-command, because */
  1961.     RTFUngetToken();                /* LaTeX deel in a good way with it */
  1962.     }
  1963. fputc('%',outfp);
  1964. output('\n',1);
  1965. if (initialised)            /* in newenvironment {} not necessary */
  1966.     {
  1967.     push_LaTeX_stack("}",Font,0);
  1968.     output_str("{",'\0');
  1969.     }
  1970. if (fontsize<5)
  1971.     {
  1972.     output_str("\\tiny ",'\0');
  1973.     return;
  1974.     }
  1975. if (fontsize<7)
  1976.     {
  1977.     output_str("\\scriptsize ",'\0');
  1978.     return;
  1979.     }
  1980. if (fontsize<9)
  1981.     {
  1982.     output_str("\\small ",'\0');
  1983.     return;
  1984.     }
  1985. if (fontsize<11)
  1986.     {
  1987.     output_str("\\normalsize ",'\0');
  1988.     return;
  1989.     }
  1990. if (fontsize<13)
  1991.     {
  1992.     output_str("\\large ",'\0');
  1993.     return;
  1994.     }
  1995. if (fontsize<17)
  1996.     {
  1997.     output_str("\\Large ",'\0');
  1998.     return;
  1999.     }
  2000. if (fontsize<21)
  2001.     {
  2002.     output_str("\\LARGE ",'\0');
  2003.     return;
  2004.     }
  2005. if (fontsize<25)
  2006.     {
  2007.     output_str("\\huge ",'\0');
  2008.     return;
  2009.     }
  2010. output_str("\\Huge ",'\0');
  2011. }
  2012.  
  2013.  
  2014. /*****************************************************************************
  2015.  *
  2016.  * set higher or lower text
  2017.  */
  2018.  
  2019. static void
  2020. set_subsuper(param)
  2021. int param;
  2022. {
  2023.       if(param == 0)
  2024.      {        /* end of a sub/superscript */
  2025.      while(!top_LaTeX_flags(Sub_Super))
  2026.         {
  2027.         if(pop_LaTeX_stack() == 0)
  2028.            {
  2029.            if(verbose)
  2030.           {
  2031.           fprintf(stderr,"%s: Failed to find end of sub/superscript\n",
  2032.             progname);
  2033.           }
  2034.            return;
  2035.            }
  2036.          }
  2037.      pop_LaTeX_stack();        /* pop off the '}' */
  2038.      if(top_LaTeX_flags(Math)) pop_LaTeX_stack(); /* and pop math too */
  2039.      return;
  2040.      }
  2041.       if (rtfMinor == rtfSuperScript)
  2042.           {
  2043.           (void)RTFGetToken();
  2044.           if (strcmp(rtfTextBuf,"\\chftn")==0)
  2045.          return;         /* we are before a footnote here */
  2046.           RTFUngetToken();        /* so we need no command, because */
  2047.           }             /* LaTeX deels with it in a good way */
  2048.       output_str("$",'\0');
  2049.       push_LaTeX_stack("$",Sub_Super,1);
  2050.       if (initialised)
  2051.           {
  2052.           output_str(rtfMinor == rtfSuperScript ? "^{" : "_{",'\0');
  2053.           push_LaTeX_stack("}",Sub_Super,rtfParam);
  2054.           }
  2055.       else
  2056.           {
  2057.           output_str(rtfMinor == rtfSuperScript ? "^" : "_",'\0');
  2058.           output_str(" \\bgroup",'\0');
  2059.           push_LaTeX_stack(" \\egroup",Sub_Super,rtfParam);
  2060.           }
  2061. }
  2062. /*****************************************************************************
  2063.  *
  2064.  * set smallcaps
  2065.  */
  2066.  
  2067. static void
  2068. set_smallcaps()
  2069. {
  2070. fputc('%',outfp);
  2071. output('\n',1);
  2072. if (initialised)
  2073.       {
  2074.       output_str("{",'\0');
  2075.       push_LaTeX_stack("}",Font,0);
  2076.       }
  2077. output_str("\\sc ",'\0');
  2078. }
  2079.  
  2080. /*****************************************************************************
  2081.  *
  2082.  * Print a string, ensuring that we are in math mode at the time
  2083.  */
  2084. static void
  2085. in_math(str)
  2086. char *str;
  2087. {
  2088.       output('$',0);
  2089.       output_str(str,'\0');
  2090.       output('$',0);
  2091. }
  2092.  
  2093. /*****************************************************************************
  2094.  *
  2095.  * Write a character, filling the the output text as we go. Characters
  2096.  * special to LaTeX are treated appropriately.
  2097.  */
  2098. #define FILL_COLUMN 60            /* column to fill to */
  2099. #define MAX_COLUMN 80            /* max of column*/
  2100. static int column=0;            /* current column */
  2101. static void
  2102. output(c,quote)
  2103. int c;                    /* The char to print */
  2104. int quote;                /* quote LaTeX's special chars? */
  2105. {
  2106.    char temp[25];
  2107.    c &= '\377';                /* prevent sign extension */
  2108.  
  2109.    if(isspace(c))
  2110.       {
  2111.       if(c == '\n')
  2112.     {
  2113.     fputc('\n',outfp);
  2114.     column=0;
  2115.     }
  2116.       else
  2117.     {
  2118.     fputc(' ',outfp);
  2119.     column++;
  2120.     if (column>FILL_COLUMN)
  2121.         {
  2122.         fputc('\n',outfp);
  2123.         column=0;
  2124.         }
  2125.     }
  2126.       return;
  2127.       }
  2128.  
  2129.    if(quote) {
  2130.       switch (rtf_ptr->char_attr.FontType) {
  2131.        case rtfFFTech:            /* A technical font */
  2132.      {
  2133.         char *str;
  2134.  
  2135.         str = (c < 128) ? symbol[c] : symbol8[c & '\177'];
  2136.         if(*str == '\0') {
  2137.            /* if(verbose) { */
  2138.           fprintf(stderr,"%s: Unknown Tech character: 0x%x\n",
  2139.             progname,c);
  2140.            /* } */
  2141.         }
  2142.         if(verbose) {
  2143.           fprintf(stderr,"A Tech character: 0x%x\n",c);
  2144.         }
  2145.         in_math(str);
  2146.      }
  2147.      return;
  2148.        default:
  2149.      switch (c)
  2150.       {            /* deal with various characters */
  2151.       case '%': case '$':
  2152.       case '#': case '&':
  2153.       case '_':
  2154.         fputc('\\',outfp);
  2155.         column++;
  2156.         break;
  2157.       case '^':
  2158.         output_str("$^{\\wedge}$",'\0');
  2159.         return;
  2160.       case '"':
  2161.         if(translate_quotes)
  2162.         c = (quotecount++ % 2) ? '\'' : '`';
  2163.         else
  2164.         c = '`';
  2165.         fputc(german_dquotes ? '"' : c, outfp);
  2166.         column++;
  2167.         break;
  2168.       case '<': case '>':
  2169.       case '|':
  2170.         sprintf(temp,"%c",c);
  2171.         in_math(temp);
  2172.         return;
  2173.       case '{': case '}':
  2174.         sprintf(temp,"\\%c",c);
  2175.         in_math(temp);
  2176.         return;
  2177.       case '\\':
  2178.         in_math("\\backslash");
  2179.         return;
  2180.       case '~':
  2181.         in_math("\\sim");
  2182.         c = ' ';
  2183.         return;
  2184.       default:
  2185.         if(!isascii(c))
  2186.            {
  2187.            output_8bit(c);
  2188.            return;
  2189.            }
  2190.         if(!isalnum(c) && !ispunct(c))
  2191.            {
  2192.            if (verbose)
  2193.           fprintf(stderr,"%s: Unknown 7-bit character: 0x%x\n",
  2194.              progname,c);
  2195.            return;
  2196.            }
  2197.         break;
  2198.      }
  2199.       }
  2200.    }
  2201. fputc(c,outfp);
  2202. column++;
  2203. }
  2204. /*****************************************************************************
  2205.  *
  2206.  * Output an entire word, without trying to quote any special characters.
  2207.  * The character C is then output using output(), which allows proper page
  2208.  * breaks.
  2209.  */
  2210.  
  2211. static void
  2212. output_str(str,c)
  2213. char *str;
  2214. int c;
  2215. {
  2216. int len = strlen(str);
  2217. int zeiger=0;
  2218. if(c != '\0')
  2219.       {
  2220.       output(c,1);
  2221.       }
  2222. if (column==0 && str[0]=='\n')
  2223.       str++;
  2224. if (str[0]=='\n')
  2225.     fputc('%',outfp);
  2226. fprintf(outfp,"%s",str);
  2227. column+=len;
  2228. if (str[0] =='\n')
  2229.     column=len;
  2230. if (str[len-1] == '\n')
  2231.     column=0;
  2232. }
  2233.  
  2234. /*****************************************************************************
  2235.  *
  2236.  * Deal with special characters above \177.
  2237.  */
  2238.  
  2239.  
  2240. typedef struct Char8bit
  2241. {
  2242. int nr;                    /* RTF-code */
  2243. char *str;                            /* LaTeX command  */
  2244. struct Char8bit *next;
  2245. }char8;
  2246.  char8 *list_8bit;            /* begin of the 8bit list */
  2247.  char8 *help;
  2248.  
  2249.  
  2250. /*****************************************************************************
  2251.  *
  2252.  *   write a 8bit character
  2253.  */
  2254.  
  2255. static void
  2256. output_8bit(c)
  2257. int c;
  2258. {
  2259.    char *str;
  2260.  
  2261. help=list_8bit;
  2262. while(help->nr!=c && help->next!=NULL)        /* search for the character*/
  2263.     help=help->next;
  2264. if (help->nr==c)
  2265.       {
  2266.       output_str(help->str,'\0');            /* and write it */
  2267.       }
  2268. else
  2269.       {                                        /* character not found */
  2270.       if(verbose)
  2271.      {
  2272.      static count=0;
  2273.      fprintf(stderr,"%s: Unknown 8-bit character: 0x%x\n",progname,c);
  2274.      if (count++<1||verbose>1)
  2275.         fprintf(stderr,"   Have a look in the file .cod\n");
  2276.      }
  2277.       }
  2278. }
  2279. /*****************************************************************************
  2280.  *
  2281.  *   read the file mac.code (or an other file e.g. ansi.code: use flag -C)
  2282.  *   and store the commands for characters with the 8bit set in the list
  2283.  *   "list_8bit"
  2284.  */
  2285.  
  2286.  
  2287. static void
  2288. read_code_file(codefile)
  2289. char *codefile;
  2290. {
  2291.  
  2292. char line[line_length];
  2293. int pos;
  2294.  
  2295. open_code_file(codefile);
  2296. if (fgets(line,line_length,fpcode)==NULL)
  2297.     {
  2298.     fprintf(stderr,"\n%s: Incorrect file a8bit    \
  2299.             \nat first there must be a number of the ascii character with msb set  \
  2300.             \n(between 128 and 255)\n",progname);
  2301.     exit(1);
  2302.     }
  2303.     for (pos=23;line[pos]==' ';pos--);
  2304.     line[pos+1]='\0';            /* cut the comment in the file*/
  2305.     list_8bit=(struct Char8bit *)malloc((int)sizeof(struct Char8bit));
  2306.     if (list_8bit==(struct Char8bit *)NULL)
  2307.         {
  2308.         fprintf(stderr,"%s: TCErr - cannot allocate a 8bit-character name\n", progname);
  2309.         exit(1);
  2310.                 }
  2311.     sscanf(line,"%d",&(list_8bit->nr));
  2312.     list_8bit->str=StrSave(line+4);
  2313.     if (list_8bit->nr<128 || list_8bit->nr>255)
  2314.         {
  2315.         fprintf(stderr,"\n%s: Incorrect file a8bit  \
  2316.                 \nat first there must be a number of the ascii character with msb set  \
  2317.                 \n(between 128 and 255)\n", progname);
  2318.         exit(1);
  2319.         }
  2320.     list_8bit->next=NULL;
  2321. while (fgets(line,line_length,fpcode)!=NULL)
  2322.     {
  2323.     for (pos=23;line[pos]==' ';pos--);
  2324.     line[pos+1]='\0';
  2325.     help=(struct Char8bit *)malloc((int)sizeof(struct Char8bit));
  2326.     if (help==(struct Char8bit *)NULL)
  2327.         {
  2328.         fprintf(stderr,"%s: SSErr - cannot allocate a 8bit-character name\n", progname);
  2329.         exit(1);
  2330.                 }
  2331.     help->next=list_8bit;
  2332.     list_8bit=help;
  2333.     sscanf(line,"%d",&(list_8bit->nr));
  2334.     list_8bit->str=StrSave(line+4);
  2335.     if (list_8bit->nr<128 || list_8bit->nr>255)
  2336.         {
  2337.         fprintf(stderr,"\n%s: Incorrect file a8bit  \
  2338.                 \nat first there must be a number of the ascii character with msb set  \
  2339.                 \n(between 128 and 255)\n", progname);
  2340.         exit(1);
  2341.                 }
  2342.     }
  2343. if (fpcode!=NULL) fclose(fpcode);
  2344. }
  2345.  
  2346.  
  2347. /*****************************************************************************
  2348.  *
  2349.  * write an errormassage to stderr
  2350.  *
  2351.  */
  2352. static void
  2353. p6(proc_name)
  2354. char *proc_name;    /*name of ther procedure where the mistake must be */
  2355. {
  2356.      fprintf(stderr," %s: Problem in procedure %s\n",progname,proc_name);
  2357.      fprintf(stderr,"           please call Erwin Wechtl\n");
  2358.      fprintf(stderr,"                       W""ortgasse 2/18\n");
  2359.      fprintf(stderr,"                       A-2500 Baden\n");
  2360.      fprintf(stderr,"                       Austria\n");
  2361.      fprintf(stderr,"                       Tel.: 43/2252/44686\n");
  2362. }
  2363.  
  2364. /*****************************************************************************
  2365.  *
  2366.  * set end af table
  2367.  */
  2368.  
  2369. static void
  2370. end_table()
  2371. {
  2372.     table_mode=0;
  2373.     if (top_LaTeX_flags(Tabular))
  2374.         {
  2375.         Cformatting_char=formatting_char;
  2376.         Cformatting_para=formatting_para;
  2377.         pop_LaTeX_stack();
  2378.         tabinitold[0]='\0';
  2379.         output_str("\n  \n",'\0');
  2380.         }
  2381. }
  2382.  
  2383.  
  2384. /*****************************************************************************
  2385.  *
  2386.  *  translate each RTF-style into a new LaTeX environment
  2387.  *  and look for special WORD styles like heading (tranlated into section)
  2388.  *  or footer (ignored)
  2389.  */
  2390. LATEXStyle *LaTeXstyleList;        /* we can't use the RTFstylelist
  2391.                        because we need more variables */
  2392.  
  2393. void DefineStyles()
  2394. {
  2395. RTFStyle   *rtfstyle;            /* the style to deel with */
  2396. LATEXStyle *LaTeXstyle;            /* the style to deel with */
  2397.  
  2398. output_str("\n \n",'\0');
  2399. LaTeXstyleList=(LATEXStyle *)NULL;
  2400. for(rtfstyle=RTFGetStyle(-1);rtfstyle!=(RTFStyle *)NULL;rtfstyle=rtfstyle->rtfNextStyle)
  2401.    {
  2402.    LaTeXstyle=(LATEXStyle *)malloc(sizeof(struct LATEXStyle));
  2403.    if (LaTeXstyle==NULL)
  2404.     {
  2405.     fprintf(stderr,"\n%s: Can't alloc LaTeXstyle\n",progname);
  2406.     exit(1);
  2407.     }
  2408.    LaTeXstyle->stacktype=Undefined;
  2409.    LaTeXstyle->BeginCommand[0] = LaTeXstyle->EndCommand[0] = '\0';
  2410.    LaTeXstyle->special_WinwordStyle=TRUE;
  2411.    if (!is_specialWORDstyle(rtfstyle,LaTeXstyle))      /* looking for special styles */
  2412.     {
  2413.     char commandbuf[80];
  2414.     RTF_STACK rtf_save;
  2415.  
  2416.     push_rtf_group();
  2417.     rtf_save = rtf_current;
  2418.     LaTeXstyle->special_WinwordStyle=FALSE;
  2419.     LaTeX_name(rtfstyle->rtfSName);
  2420.     strcpy(commandbuf,"\n\\");
  2421.     strcat(commandbuf,"begin{");
  2422.     strcat(commandbuf,rtfstyle->rtfSName);
  2423.     strcat(commandbuf,"}\n");
  2424.     strcpy(LaTeXstyle->BeginCommand,commandbuf);
  2425.     strcpy(commandbuf,"\n\\");
  2426.     strcat(commandbuf,"end{");
  2427.     strcat(commandbuf,rtfstyle->rtfSName);
  2428.     strcat(commandbuf,"}\n");
  2429.     strcpy(LaTeXstyle->EndCommand,commandbuf);
  2430.  
  2431.     output_str("\n% definition of ",'\0');
  2432.     output_str(rtfstyle->rtfSName,'\0');
  2433.     output_str("\n\\newenvironment{",'\0');
  2434.     output_str(rtfstyle->rtfSName,'\0');
  2435.     output_str("}{",'\0');
  2436.  
  2437.     RTFExpandStyle(rtfstyle->rtfSNum);
  2438.     LaTeXstyle->char_attr=rtf_ptr->char_attr;
  2439.     LaTeXstyle->par_attr=rtf_ptr->par_attr;
  2440.     LaTeXstyle->stacktype=NormalWORDstyle;
  2441.     update_current();
  2442.     output_str("}{",'\0');
  2443.     while(pop_LaTeX_stack()) continue;
  2444.     output_str("}\n",'\0');
  2445.  
  2446.     rtf_current = rtf_save;
  2447.     pop_rtf_group();
  2448.     }
  2449.   LaTeXstyle->rtfSNum=rtfstyle->rtfSNum;
  2450.   LaTeXstyle->rtfSName=rtfstyle->rtfSName;
  2451.   LaTeXstyle->LaTeXNextStyle=LaTeXstyleList;
  2452.   LaTeXstyleList=LaTeXstyle;
  2453.    }
  2454. if (fpland!=NULL) fclose(fpland);
  2455. }
  2456.  
  2457. /*****************************************************************************
  2458.  *
  2459.  *   begin a style environment
  2460.  */
  2461.  
  2462.  
  2463. void setstylecommand(n)
  2464. int    n;            /* rtfStyleNumber */
  2465. {
  2466. LATEXStyle    *LaTeXstyle;
  2467. RTFStyle        *rtfstyle;
  2468. char buf[80];
  2469.  
  2470.     if(!table_mode && top_LaTeX_flags(Tabular))
  2471.         end_table();
  2472.     LaTeXstyle=LaTeXstyleList;
  2473.     while (LaTeXstyle!=NULL && LaTeXstyle->rtfSNum!=n) LaTeXstyle=LaTeXstyle->LaTeXNextStyle;
  2474.     if (LaTeXstyle==NULL)
  2475.         {
  2476.         static int count=0;
  2477.  
  2478.         rtfstyle=RTFGetStyle(n);
  2479.         if (verbose>1 || (verbose && count++==0))
  2480.             {
  2481.             fprintf(stderr,"%s: There are some troubles with the style %s with the number %d, \n  so this style is ignored\n",
  2482.                 progname,rtfstyle->rtfSName,n);
  2483.             }
  2484. # ifdef notdef /* Don't know if this is needed anymore */
  2485. /*        sprintf(buf,"\n%% The Style %s with the number %d may begin here\n",rtfstyle->rtfSName,n);
  2486.         output_str(buf,'\0');
  2487.         output_str("%%But rtf2LaTeX has had some troubles with it",'\0');
  2488.         sprintf(buf,"\n%  The Style %s with the number %d may end here\n",rtfstyle->rtfSName,n);
  2489.         push_LaTeX_stack(buf,NormalWORDstyle,0);
  2490. */
  2491. # endif /* notdef */
  2492.         return;
  2493.         }
  2494.     if (LaTeXstyle->special_WinwordStyle)    /* if heading,footer, ... */
  2495.         {       /* use paragraph(character) formating only
  2496.                if the flag -d is on             */
  2497.         Cformatting_para=formatting_sWORD&&formatting_para;
  2498.         Cformatting_char=formatting_sWORD&&formatting_char;
  2499.         }
  2500.     else
  2501.         {
  2502.         update_current();    /* format */
  2503.         rtf_current.par_attr=LaTeXstyle->par_attr;
  2504.         rtf_current.char_attr=LaTeXstyle->char_attr;
  2505.         rtf_ptr->par_attr=LaTeXstyle->par_attr;
  2506.         rtf_ptr->char_attr=LaTeXstyle->char_attr;
  2507.         rtf_current.LaTeX_stack = NULL;
  2508.         rtf_current.prev = NULL;
  2509.         }
  2510.     output_str(LaTeXstyle->BeginCommand,'\0');
  2511.     push_LaTeX_stack(LaTeXstyle->EndCommand,LaTeXstyle->stacktype,0);
  2512. }
  2513.  
  2514. /*****************************************************************************
  2515.  *
  2516.  *  look in the file english.land (or an other file e.g. german.land:
  2517.  *  use flag -L)
  2518.  *  if this is a Spezial WORD style like heading, footer, ...
  2519.  */
  2520.  
  2521.  
  2522. int
  2523. is_specialWORDstyle(rtfstyle,LaTeXstyle)
  2524. RTFStyle    *rtfstyle;
  2525. LATEXStyle    *LaTeXstyle;
  2526.  
  2527. {
  2528. char line[line_length];                         /* the line which is read from the file */
  2529.  
  2530. if (formatting_sWORD)                /* if flag -d is on */
  2531.     return(0);                /* use WORD formate instead of LaTeX formate within header, ... */
  2532. fseek(fpland, 0, SEEK_SET);
  2533. while (fgets(line,line_length,fpland)!=NULL)
  2534.     {
  2535.     if (strncmp(rtfstyle->rtfSName,line,strlen(rtfstyle->rtfSName))==0)
  2536.         {
  2537.         LaTeXstyle->stacktype=SpecialWORDstyle;
  2538.         if (strncmp(line+20,"           ",10)!=0)
  2539.             sscanf(line+20,"%20s%20s",LaTeXstyle->BeginCommand,LaTeXstyle->EndCommand);
  2540.         else
  2541.             LaTeXstyle->BeginCommand[0] = LaTeXstyle->EndCommand[0] = '\0';
  2542.         output_str("% ",'\0');
  2543.         output_str(line+60,'\0');
  2544.         return(1);
  2545.         }
  2546.     }
  2547. return(0);
  2548. }
  2549.  
  2550. /*****************************************************************************
  2551.  *
  2552.  *   malloc for a string
  2553.  */
  2554.  
  2555.  
  2556. static char *StrSave (s)
  2557. char    *s;
  2558. {
  2559. char    *p;
  2560.  
  2561.     if ((p = (char *)malloc (strlen (s) + 1)) == (char *) NULL)
  2562.         fprintf(stderr,"%s: Error in malloc\n",progname);
  2563.     return (strcpy (p, s));
  2564. }
  2565.  
  2566.  
  2567. /*****************************************************************************
  2568.  *
  2569.  *   set the position of the Tabstops and output the begin environment
  2570.  */
  2571.  
  2572.  
  2573. static void
  2574. start_tabstops()
  2575. {
  2576.    int i,j;
  2577.    int width;                /* width of table entry (twips) */
  2578.    char buf[1];
  2579.  
  2580.    if (top_LaTeX_flags(SpecialWORDstyle))
  2581.     return;               /* no tab stops in header, heading, ...*/
  2582.    Cformatting_char=formatting_char&&formatting_table;
  2583.    Cformatting_para=formatting_para&&formatting_table;
  2584.    output_str("\n\\begin{tabbing}\n",'\0');
  2585.    for(i = 0;i < NTABS;i++)
  2586.       {
  2587.       width = tabstops[i].pos;
  2588.       if(i > 0)
  2589.     width -= tabstops[i - 1].pos;
  2590.       width=TW_TO_CA(width);
  2591.       if (width<1)
  2592.     continue;
  2593.       for(j=1;j<=width;j++)
  2594.     {
  2595.     sprintf(buf,"%d",(j % 10));
  2596.     output_str(buf,'\0');
  2597.     }
  2598.       output_str("\\=",'\0');
  2599.       }
  2600.    output_str("\\kill\n",'\0');
  2601.    push_LaTeX_stack("\\end{tabbing}\n",Tabstops,0);
  2602.    tabstopsInit();
  2603.    tab=2;
  2604. }
  2605.  
  2606. /*****************************************************************************
  2607.  *
  2608.  *   initialise the array of the Tabstops-positions
  2609.  */
  2610.  
  2611. static void
  2612. tabstopsInit()
  2613. {
  2614. int i;
  2615.  
  2616. for (i=0;i<NTABS;i++)
  2617.     {
  2618.     tabstops[i].pos=CA_TO_TW(i*defaultTabWidth);
  2619.     tabstops[i].type=0;
  2620.     }
  2621.     ntabs=0;
  2622. }
  2623.  
  2624. /*****************************************************************************
  2625.  *
  2626.  * Stack stuff -- RTF and LaTeX grouping go on separate stacks
  2627.  *
  2628.  * pop the status stack, putting the free'd element on the free list
  2629.  */
  2630. static RTF_STACK *rtf_free_list = NULL;
  2631. static void
  2632. pop_rtf_group()
  2633. {
  2634.    RTF_STACK *temp;
  2635.  
  2636.    if(rtf_ptr->prev == NULL) {
  2637.       fprintf(stderr,"%s: Attempt to pop an empty stack\n", progname);
  2638.       abort();
  2639.    }
  2640.    temp = rtf_ptr->prev;
  2641.    rtf_ptr->prev = rtf_free_list;
  2642.    rtf_free_list = rtf_ptr;
  2643.    rtf_ptr = temp;
  2644. }
  2645. /*
  2646.  * push the RTF status stack
  2647.  */
  2648. static void
  2649. push_rtf_group()
  2650. {
  2651.    RTF_STACK *temp;
  2652.    /*#ifdef __riscos
  2653.    register char *s,*d,*to;
  2654.    #endif*/
  2655.  
  2656.    if(rtf_free_list != NULL) {
  2657.       temp = rtf_free_list;
  2658.       rtf_free_list = rtf_free_list->prev;
  2659.    } else {
  2660.       if((temp = (RTF_STACK *)malloc(sizeof(RTF_STACK))) == NULL) {
  2661.      fprintf(stderr,"%s: Can't allocate storage for stack\n",progname);
  2662.      exit(1);
  2663.       }
  2664.    }
  2665.    /*#ifdef __riscos
  2666.    s = (char*)rtf_ptr; d = (char*)temp; to = s + sizeof(RTF_STACK);
  2667.    while (s < to) {*d++ = *s++;}
  2668.    #else*/
  2669.    memcpy((char *)temp,(char *)rtf_ptr,sizeof(RTF_STACK));
  2670.    /*#endif*/
  2671.    temp->prev = rtf_ptr;
  2672.    rtf_ptr = temp;
  2673.    rtf_ptr->LaTeX_stack = NULL;
  2674. }
  2675. /*****************************************************************************
  2676.  *
  2677.  * Now the LaTeX stacks. Use the stack in the current rtf_ptr frame
  2678.  */
  2679. static LATEX_STACK *myTeX_free_list = NULL;
  2680. static int
  2681. pop_LaTeX_stack()
  2682. {
  2683.    char *str;
  2684.    LATEX_STACK *temp;
  2685.  
  2686.    if(rtf_ptr->LaTeX_stack == NULL) {
  2687.       return(0);
  2688.    }
  2689.    if (rtf_ptr->LaTeX_stack->type == SpecialWORDstyle)
  2690.     {                    /* reset formatting      */
  2691.     Cformatting_para =formatting_para;    /* after heading, footer, .. */
  2692.     Cformatting_char=formatting_char;
  2693.     }
  2694.    LaTeX_group--;
  2695.    str = rtf_ptr->LaTeX_stack->str;
  2696.    temp = rtf_ptr->LaTeX_stack->prev;
  2697.    rtf_ptr->LaTeX_stack->prev = myTeX_free_list;
  2698.    myTeX_free_list = rtf_ptr->LaTeX_stack;
  2699.    rtf_ptr->LaTeX_stack = temp;
  2700.    output_str(myTeX_free_list->str,'\0');
  2701.    return(1);
  2702. }
  2703. /*
  2704.  * push the string STR onto the LaTeX stack, with attributes TYPE and FLAGS
  2705.  */
  2706. static void
  2707. push_LaTeX_stack(str,type,flags)
  2708. char *str;                /* string to save */
  2709. int type;                /* type of string */
  2710. long flags;                /* and corresponding flags */
  2711. {
  2712.    LATEX_STACK *temp;
  2713.    LaTeX_group++;
  2714.    if(myTeX_free_list != NULL) {
  2715.       temp = myTeX_free_list;
  2716.       myTeX_free_list = myTeX_free_list->prev;
  2717.    } else {
  2718.       if((temp = (LATEX_STACK *)malloc(sizeof(LATEX_STACK))) == NULL) {
  2719.      fprintf(stderr,"%s: Can't allocate storage for stack\n",progname);
  2720.      exit(1);
  2721.       }
  2722.    }
  2723.  
  2724.    temp->prev = rtf_ptr->LaTeX_stack;
  2725.    rtf_ptr->LaTeX_stack = temp;
  2726.    rtf_ptr->LaTeX_stack->str = str;
  2727.    rtf_ptr->LaTeX_stack->type = type;
  2728.    rtf_ptr->LaTeX_stack->flags = flags;
  2729.    return;
  2730. }
  2731. /*****************************************************************************
  2732.  *
  2733.  * Return the flags of the proper type for the top element of the LaTeX stack
  2734.  */
  2735. static int
  2736. top_LaTeX_flags(type)
  2737. int type;
  2738. {
  2739.    return((rtf_ptr->LaTeX_stack != NULL && rtf_ptr->LaTeX_stack->type == type) ?
  2740.       1 : 0);
  2741. }
  2742. /*****************************************************************************/
  2743.  
  2744.  
  2745. static void
  2746. open_code_file (codefile)
  2747. char *codefile;
  2748. {
  2749.       char *filename;
  2750.       char line[line_length];
  2751.       char c;
  2752.       if((filename = malloc(strlen(codefile) + strlen(RTFDIR) + 7)) == NULL)
  2753.       {
  2754.     fprintf(stderr,"%s: Error in malloc\n",progname);
  2755.     exit(3);
  2756.       }
  2757.       strcpy(filename,RTFDIR);
  2758. #if (!defined (THINK_C)) && (!defined (__riscos))
  2759.       strcat(filename,"/");
  2760. #endif /* !THINK_C */
  2761.       #ifdef __riscos
  2762.       strcat(filename,"code."); strcat(filename,codefile);
  2763.       #else
  2764.       strcat(filename,codefile);
  2765.       if ((strchr(codefile,'.')) == NULL)
  2766.           strcat(filename,".code");
  2767.       #endif
  2768.       if((fpcode = fopen(filename,"r")) == NULL)
  2769.      {
  2770.      fprintf(stderr,"%s: Can't open %s\n",progname,filename);
  2771.      exit(1);
  2772.      }
  2773.       free(filename);
  2774.       if (fgets(line,line_length,fpcode)==NULL)
  2775.     {
  2776.     fprintf(stderr,"\n%s: Incorrect file a8bit   \
  2777.             \nthere must be a comment in the first line\n",
  2778.             progname);
  2779.     exit(1);
  2780.     }
  2781. }
  2782. static void
  2783. open_land_file (landfile)
  2784. char *landfile;
  2785. {
  2786.       char *filename;
  2787.       if((filename = malloc(strlen(landfile) + strlen(RTFDIR) + 7)) == NULL)
  2788.       {
  2789.     fprintf(stderr,"%s: Error in malloc\n",progname);
  2790.     exit(3);
  2791.       }
  2792.       strcpy(filename,RTFDIR);
  2793. #if (!defined (THINK_C)) && (!defined (__riscos))
  2794.       strcat(filename,"/");
  2795. #endif /* !THINK_C */
  2796.       #ifdef __riscos
  2797.       strcat(filename,"land."); strcat(filename,landfile);
  2798.       #else
  2799.       strcat(filename,landfile);
  2800.       if ((strchr(landfile,'.')) == NULL)
  2801.           strcat(filename,".land");
  2802.       #endif
  2803.       if((fpland = fopen(filename,"r")) == NULL) {
  2804.      fprintf(stderr,"%s: Can't open %s\n",progname,filename);
  2805.      exit(1);
  2806.       }
  2807.       free(filename);
  2808. }
  2809.